package com.hk.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hk.enums.SpaceRoleEnum;
import com.hk.exception.BusinessException;
import com.hk.exception.ErrorCode;
import com.hk.exception.ThrowExceptionUtil;
import com.hk.mapper.SpaceUserMapper;
import com.hk.model.entity.Space;
import com.hk.model.entity.SpaceUser;
import com.hk.model.vo.space.SpaceVO;
import com.hk.model.vo.spaceuser.SpaceUserAddVO;
import com.hk.model.vo.spaceuser.SpaceUserBatchAddVO;
import com.hk.model.vo.spaceuser.SpaceUserEditVO;
import com.hk.model.vo.spaceuser.SpaceUserVO;
import com.hk.model.vo.user.UserVO;
import com.hk.service.SpaceService;
import com.hk.service.SpaceUserService;
import com.hk.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 20231
 * @description 针对表【space_user(空间用户关联)】的数据库操作Service实现
 * @createDate 2025-02-08 20:06:26
 */
@Slf4j
@Service
public class SpaceUserServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser> implements SpaceUserService {
    @Resource
    @Lazy
    private SpaceService spaceService;
    @Resource
    private UserService userService;

    @Override
    public boolean addSpaceUser(SpaceUserAddVO spaceUserAddVO) {
        Long spaceId = spaceUserAddVO.getSpaceId();
        Space space = spaceService.getById(spaceId);
        ThrowExceptionUtil.throwIf(space == null, ErrorCode.ERROR_PARAM, "空间不存在");
        SpaceUser spaceUser = new SpaceUser();
        BeanUtils.copyProperties(spaceUserAddVO, spaceUser);
        try {
            return save(spaceUser);
        } catch (Exception e) {
            log.error("添加空间用户失败", e);
            throw new BusinessException(ErrorCode.ERROR_SYSTEM, "添加空间用户失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchAddSpaceUser(SpaceUserBatchAddVO userBatchAddVO) {
        Long spaceId = userBatchAddVO.getSpaceId();
        List<Long> userIdList = userBatchAddVO.getUserIdList();
        ThrowExceptionUtil.throwIf(CollectionUtil.isEmpty(userIdList), ErrorCode.ERROR_PARAM, "用户列表不能为空");
        Space space = spaceService.getById(spaceId);
        ThrowExceptionUtil.throwIf(space == null, ErrorCode.ERROR_PARAM, "空间不存在");
        List<SpaceUser> spaceUserList = new ArrayList<>(userIdList.size());
        for (Long userId : userIdList) {
            SpaceUser spaceUser = new SpaceUser();
            spaceUser.setSpaceId(spaceId);
            spaceUser.setUserId(userId);
            spaceUser.setSpaceRole(SpaceRoleEnum.VIEWER.getValue());
            spaceUserList.add(spaceUser);
        }
        try {
            return saveBatch(spaceUserList);
        } catch (Exception e) {
            log.error("添加空间用户失败", e);
            throw new BusinessException(ErrorCode.ERROR_SYSTEM, "添加空间用户失败");
        }
    }

    @Override
    public boolean editSpaceUser(SpaceUserEditVO spaceUserEditVO) {
        Long id = spaceUserEditVO.getId();
        String spaceRole = spaceUserEditVO.getSpaceRole();
        SpaceUser spaceUser = getById(id);
        ThrowExceptionUtil.throwIf(spaceUser == null, ErrorCode.ERROR_PARAM, "空间成员不存在");
        SpaceUser newSpaceUser = new SpaceUser();
        newSpaceUser.setId(id);
        newSpaceUser.setSpaceRole(spaceRole);
        return updateById(newSpaceUser);
    }

    @Override
    public List<SpaceUserVO> getSpaceUserList(Long spaceId, String spaceRole, Long userId) {
        LambdaQueryWrapper<SpaceUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(spaceId != null, SpaceUser::getSpaceId, spaceId);
        queryWrapper.eq(StringUtils.isNotBlank(spaceRole), SpaceUser::getSpaceRole, spaceRole);
        queryWrapper.eq(userId != null, SpaceUser::getUserId, userId);
        queryWrapper.orderByDesc(SpaceUser::getCreateTime);
        List<SpaceUser> spaceUserList = list(queryWrapper);
        if (CollectionUtil.isEmpty(spaceUserList)) {
            return new ArrayList<>();
        }
        return converterVO(spaceUserList);
    }

    @Override
    public List<SpaceUserVO> selectUserListBySpaceId(Long spaceId, String spaceRole) {
        List<SpaceUserVO> spaceUserList = getSpaceUserList(spaceId, spaceRole, null);
        if (CollectionUtil.isEmpty(spaceUserList)) return new ArrayList<>();
        List<Long> userIdList = spaceUserList.stream().map(SpaceUserVO::getUserId).distinct().toList();
        List<UserVO> userList = userService.getUserListById(userIdList);
        Map<Long, UserVO> userMap = userList.stream().collect(Collectors.toMap(UserVO::getId, Function.identity()));
        spaceUserList.forEach(spaceUserVO -> spaceUserVO.setUserVO(userMap.get(spaceUserVO.getUserId())));
        return spaceUserList;
    }

    @Override
    public List<SpaceUserVO> selectSpaceListByUserId(Long userId) {
        List<SpaceUserVO> spaceUserList = getSpaceUserList(null, null, userId);
        List<Long> spaceIdList = spaceUserList.stream().map(SpaceUserVO::getSpaceId).distinct().toList();
        Map<Long, SpaceVO> spaceMap = spaceService.selectListMao(spaceIdList);
        spaceUserList.forEach(spaceUserVO -> spaceUserVO.setSpaceVO(spaceMap.get(spaceUserVO.getSpaceId())));
        return spaceUserList;
    }

    @Override
    public void deleteBySpaceId(Long spaceId) {
        this.remove(new LambdaQueryWrapper<>(SpaceUser.class).eq(SpaceUser::getSpaceId, spaceId));
    }

    private SpaceUserVO converterVO(SpaceUser spaceUser) {
        if (spaceUser == null) return null;
        SpaceUserVO spaceUserVO = new SpaceUserVO();
        BeanUtils.copyProperties(spaceUser, spaceUserVO);
        return spaceUserVO;
    }

    private List<SpaceUserVO> converterVO(List<SpaceUser> spaceUserList) {
        if (CollectionUtil.isEmpty(spaceUserList)) return new ArrayList<>();
        return spaceUserList.stream().map(this::converterVO).collect(Collectors.toList());
    }

}




